import structlog
import logging
import sys
from typing import Any, Dict
from datetime import datetime
from colorama import Fore, Back, Style, init

from .config import settings

# 初始化colorama以支持Windows控制台颜色
init(autoreset=True)


def console_renderer(logger, method_name, event_dict):
    """
    美观的控制台日志渲染器
    将结构化日志转换为彩色、易读的控制台输出
    """
    # 获取日志级别颜色
    level_colors = {
        "debug": Fore.CYAN,
        "info": Fore.GREEN,
        "warning": Fore.YELLOW,
        "error": Fore.RED,
        "critical": Fore.MAGENTA + Style.BRIGHT
    }
    
    level = event_dict.get("level", "info")
    timestamp = event_dict.get("timestamp", "")
    event = event_dict.get("event", "")
    
    # 格式化时间戳（只显示时分秒）
    if timestamp:
        try:
            dt = datetime.fromisoformat(timestamp.replace('Z', '+00:00'))
            time_str = dt.strftime("%H:%M:%S")
        except:
            time_str = timestamp[:8] if len(timestamp) > 8 else timestamp
    else:
        time_str = datetime.now().strftime("%H:%M:%S")
    
    # 构建基础日志行
    level_color = level_colors.get(level, Fore.WHITE)
    level_str = f"{level_color}[{level.upper():^8}]{Style.RESET_ALL}"
    time_str = f"{Fore.BLUE}{time_str}{Style.RESET_ALL}"
    
    # 处理特殊事件类型
    event_type = event_dict.get("event_type")
    if event_type == "database_connection":
        status = event_dict.get("status", "unknown")
        host = event_dict.get("host", "")
        port = event_dict.get("port", "")
        database = event_dict.get("database", "")
        
        if status == "success":
            icon = f"{Fore.GREEN}✓{Style.RESET_ALL}"
            event = f"{icon} 数据库连接成功 {Fore.CYAN}{host}:{port}/{database}{Style.RESET_ALL}"
        else:
            icon = f"{Fore.RED}✗{Style.RESET_ALL}"
            event = f"{icon} 数据库连接失败 {Fore.CYAN}{host}:{port}/{database}{Style.RESET_ALL}"
    
    elif event_type == "sql_query":
        duration = event_dict.get("duration_ms", 0)
        query = event_dict.get("query", "")
        icon = f"{Fore.BLUE}🔍{Style.RESET_ALL}"
        event = f"{icon} SQL查询 {Fore.YELLOW}({duration}ms){Style.RESET_ALL} {Fore.WHITE}{query[:50]}...{Style.RESET_ALL}"
    
    elif event_type == "transaction":
        action = event_dict.get("action", "")
        if action == "start":
            icon = f"{Fore.BLUE}▶{Style.RESET_ALL}"
        elif action == "commit":
            icon = f"{Fore.GREEN}✓{Style.RESET_ALL}"
        elif action == "rollback":
            icon = f"{Fore.RED}↺{Style.RESET_ALL}"
        else:
            icon = f"{Fore.WHITE}•{Style.RESET_ALL}"
        event = f"{icon} 事务{action} {event}"
    
    else:
        # 普通日志事件
        if level == "info":
            icon = f"{Fore.GREEN}ℹ{Style.RESET_ALL}"
        elif level == "warning":
            icon = f"{Fore.YELLOW}⚠{Style.RESET_ALL}"
        elif level == "error":
            icon = f"{Fore.RED}✗{Style.RESET_ALL}"
        elif level == "debug":
            icon = f"{Fore.CYAN}🔧{Style.RESET_ALL}"
        else:
            icon = f"{Fore.WHITE}•{Style.RESET_ALL}"
        
        event = f"{icon} {event}"
    
    # 添加文件信息（仅在debug模式下）
    filename = event_dict.get("filename", "")
    func_name = event_dict.get("func_name", "")
    lineno = event_dict.get("lineno", "")
    
    if settings.debug and filename:
        location = f"{Fore.BLACK + Style.BRIGHT}[{filename}:{func_name}:{lineno}]{Style.RESET_ALL}"
        event = f"{event} {location}"
    
    # 构建最终输出
    return f"{time_str} {level_str} {event}"


def setup_logging() -> None:
    """
    配置结构化日志
    使用structlog提供美观的控制台日志输出
    """
    
    # 配置标准库logging
    logging.basicConfig(
        format="%(message)s",
        stream=sys.stdout,
        level=getattr(logging, settings.log_level.upper()),
    )
    
    # 配置structlog
    structlog.configure(
        processors=[
            # 添加时间戳
            structlog.processors.TimeStamper(fmt="iso"),
            # 添加日志级别
            structlog.stdlib.add_log_level,
            # 添加调用者信息
            structlog.processors.CallsiteParameterAdder(
                parameters=[structlog.processors.CallsiteParameter.FILENAME,
                           structlog.processors.CallsiteParameter.FUNC_NAME,
                           structlog.processors.CallsiteParameter.LINENO]
            ),
            # 美观的控制台渲染器
            console_renderer
        ],
        wrapper_class=structlog.stdlib.BoundLogger,
        logger_factory=structlog.stdlib.LoggerFactory(),
        context_class=dict,
        cache_logger_on_first_use=True,
    )


def get_logger(name: str) -> structlog.BoundLogger:
    """
    获取结构化日志记录器
    
    Args:
        name: 日志记录器名称，通常使用 __name__
    
    Returns:
        配置好的结构化日志记录器
    """
    return structlog.get_logger(name)


class DatabaseLogHandler:
    """
    数据库操作日志处理器
    专门用于记录数据库相关的操作日志
    """
    
    def __init__(self):
        self.logger = get_logger("database")
    
    def log_connection_success(self, **kwargs: Any) -> None:
        """
        记录数据库连接成功日志
        """
        self.logger.info(
            "数据库连接成功",
            event_type="database_connection",
            status="success",
            timestamp=datetime.now().isoformat(),
            **kwargs
        )
    
    def log_connection_error(self, error: Exception, **kwargs: Any) -> None:
        """
        记录数据库连接错误日志
        """
        self.logger.error(
            "数据库连接失败",
            event_type="database_connection",
            status="error",
            error_type=type(error).__name__,
            error_message=str(error),
            timestamp=datetime.now().isoformat(),
            **kwargs
        )
    
    def log_query_execution(self, query: str, duration: float, **kwargs: Any) -> None:
        """
        记录SQL查询执行日志
        """
        self.logger.info(
            "SQL查询执行",
            event_type="sql_query",
            query=query[:200] + "..." if len(query) > 200 else query,  # 截断长查询
            duration_ms=round(duration * 1000, 2),
            timestamp=datetime.now().isoformat(),
            **kwargs
        )
    
    def log_transaction_start(self, **kwargs: Any) -> None:
        """
        记录事务开始日志
        """
        self.logger.debug(
            "数据库事务开始",
            event_type="transaction",
            action="start",
            timestamp=datetime.now().isoformat(),
            **kwargs
        )
    
    def log_transaction_commit(self, **kwargs: Any) -> None:
        """
        记录事务提交日志
        """
        self.logger.debug(
            "数据库事务提交",
            event_type="transaction",
            action="commit",
            timestamp=datetime.now().isoformat(),
            **kwargs
        )
    
    def log_transaction_rollback(self, error: Exception = None, **kwargs: Any) -> None:
        """
        记录事务回滚日志
        """
        log_data = {
            "event_type": "transaction",
            "action": "rollback",
            "timestamp": datetime.now().isoformat(),
            **kwargs
        }
        
        if error:
            log_data.update({
                "error_type": type(error).__name__,
                "error_message": str(error)
            })
        
        self.logger.warning("数据库事务回滚", **log_data)


# 全局数据库日志处理器实例
db_log_handler = DatabaseLogHandler()